using Avalonia.Input.Platform;
using CommunityToolkit.Mvvm.Input;
using DesktopApp.ViewModels.Services;
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Windows.Input;
using CommunityToolkit.Mvvm.ComponentModel;

namespace DesktopApp.ViewModels
{
    public partial class LogPanelViewModel : ViewModelBase
    {
        private readonly ILogFileService _logFileService;
        // Add IUIService if needed for dialogs related to log panel actions

        [ObservableProperty]
        private string _originalLogText = string.Empty;

        [ObservableProperty]
        private string? _selectedOriginalLogText;

        // Make public setter accessible by StatusBarVM after processing
        [ObservableProperty]
        private string _resultLogText = string.Empty;

        // Event for statistics recalculation
        public event EventHandler? LogTextChanged;

        // Event to explicitly notify RulesViewModel
        public event EventHandler? SelectedOriginalLogTextChanged;

        // Commands
        public ICommand CopyResultCommand { get; }
        public ICommand ClearLogsCommand { get; }
        public ICommand PasteLogCommand { get; }
        public ICommand OpenLogCommand { get; }
        public ICommand SaveResultCommand { get; }

        public LogPanelViewModel(ILogFileService logFileService /*, IUIService uiService */)
        {
            _logFileService = logFileService;
            // _uiService = uiService; 

            // Initialize Commands
            CopyResultCommand = new AsyncRelayCommand(CopyResultToClipboard, CanCopyResultToClipboard);
            ClearLogsCommand = new RelayCommand(ClearLogs, CanClearLogs);
            PasteLogCommand = new AsyncRelayCommand(PasteLog);
            OpenLogCommand = new AsyncRelayCommand(OpenLog);
            SaveResultCommand = new AsyncRelayCommand(SaveResult, CanSaveResult);
        }

        // Command Implementations
        private async Task CopyResultToClipboard()
        {
            if (string.IsNullOrEmpty(ResultLogText)) return;
            bool success = await _logFileService.CopyTextToClipboardAsync(ResultLogText);
            if (success)
            {
                 Debug.WriteLine("LogPanelViewModel: Result copied to clipboard.");
                 // Optionally use _uiService to show confirmation
            }
            else
            {
                Debug.WriteLine("LogPanelViewModel: Failed to copy result.");
                // Optionally use _uiService to show error
            }
        }

        private bool CanCopyResultToClipboard()
        {
            bool canExecute = !string.IsNullOrEmpty(ResultLogText);
            Debug.WriteLine($"[LogPanelViewModel] CanCopyResultToClipboard called. ResultLogText empty: {string.IsNullOrEmpty(ResultLogText)}, Result: {canExecute}"); // Log inside CanExecute
            return canExecute;
        }

        private void ClearLogs(object? parameter)
        {
            Debug.WriteLine("LogPanelViewModel: ClearLogs command executed.");
            OriginalLogText = string.Empty;
            ResultLogText = string.Empty;
            // LogTextChanged event will handle stat updates
        }

        private bool CanClearLogs(object? parameter)
        {
             return !string.IsNullOrEmpty(OriginalLogText) || !string.IsNullOrEmpty(ResultLogText);
        }

        private async Task PasteLog()
        {
            var pastedText = await _logFileService.PasteLogAsync();
            if (pastedText != null) // Service returns nullable string
            {
                OriginalLogText = pastedText;
                // LogTextChanged event will handle stat updates
            }
            else
            {
                Debug.WriteLine("LogPanelViewModel: Paste operation returned null or empty text.");
                // Optionally use _uiService to show message
            }
        }

        // CanPasteLog might depend on clipboard state, often assumed true
        // private bool CanPasteLog() => true;

        private async Task OpenLog()
        {
            var logContent = await _logFileService.OpenLogAsync();
            if (logContent != null)
            {
                OriginalLogText = logContent;
                // LogTextChanged event will handle stat updates
            }
            // No action needed if null (user cancelled or error in service)
        }

        private async Task SaveResult()
        {
            if (!CanSaveResult()) return;
            bool success = await _logFileService.SaveResultAsync(ResultLogText);
            if (success)
            {
                Debug.WriteLine("LogPanelViewModel: Result saved successfully.");
                // Optionally use _uiService to show confirmation
            }
            else
            {
                Debug.WriteLine("LogPanelViewModel: Failed to save result.");
                // Error should be handled/shown by the service or use _uiService here
            }
        }

        private bool CanSaveResult()
        {
            return !string.IsNullOrEmpty(ResultLogText);
        }

        // Manually handle ResultLogText property change to trigger command updates
        partial void OnResultLogTextChanged(string? oldValue, string newValue)
        {
             Debug.WriteLine($"[LogPanelViewModel] ResultLogText property changed (via OnResultLogTextChanged). Old empty: {string.IsNullOrEmpty(oldValue)}, New empty: {string.IsNullOrEmpty(newValue)}");
             LogTextChanged?.Invoke(this, EventArgs.Empty);
             (CopyResultCommand as AsyncRelayCommand)?.NotifyCanExecuteChanged();
             (SaveResultCommand as AsyncRelayCommand)?.NotifyCanExecuteChanged();
        }

        // Manually handle OriginalLogText property change
        partial void OnOriginalLogTextChanged(string? oldValue, string newValue)
        {
            // Add logging BEFORE raising the event
            Debug.WriteLine("[LogPanelViewModel] OriginalLogText setter: About to raise LogTextChanged.");
            LogTextChanged?.Invoke(this, EventArgs.Empty);
            // Also notify CanClearLogs if OriginalLogText changes
            (ClearLogsCommand as RelayCommand<object?>)?.NotifyCanExecuteChanged();
        }

        // Manually handle SelectedOriginalLogText property change to raise event
        partial void OnSelectedOriginalLogTextChanged(string? oldValue, string? newValue)
        {
             SelectedOriginalLogTextChanged?.Invoke(this, EventArgs.Empty);
             // Debug log if needed
             // Debug.WriteLine($\"[LogPanelViewModel] SelectedOriginalLogTextChanged raised. New value: '{newValue ?? \"null\"}\'");
        }
    }
} 